{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "origin_pos": 0
   },
   "source": [
    "# Truth Value Testing: `all` and `any`\n",
    ":label:`ch_all_any`\n",
    "\n",
    "In Python, we can use `all` and `any` to get the boolean return of a list of values. `all` returns the logical `and` result while `any` returns the logical `or` result.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "origin_pos": 1,
    "tab": [
     "tvm"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(True, False)"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import d2ltvm \n",
    "import tvm\n",
    "from tvm import te\n",
    "\n",
    "any((0, 1, 2)), all((0, 1, 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "origin_pos": 2
   },
   "source": [
    "TVM provides similar `te.all` and `te.any`, which are useful to construct complex conditional expression for `te.if_then_else`. \n",
    "\n",
    "The example we will use is padding the matrix `a` with 0s.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "attributes": {
     "classes": [],
     "id": "",
     "n": "3"
    },
    "origin_pos": 3,
    "tab": [
     "tvm"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0. 0. 0. 0. 0. 0.]\n",
      " [0. 1. 1. 1. 1. 0.]\n",
      " [0. 1. 1. 1. 1. 0.]\n",
      " [0. 1. 1. 1. 1. 0.]\n",
      " [0. 0. 0. 0. 0. 0.]]\n"
     ]
    }
   ],
   "source": [
    "a = np.ones((3, 4), dtype='float32')\n",
    "# applying a zero padding of size 1 to a\n",
    "b = np.zeros((5, 6), dtype='float32')\n",
    "b[1:-1,1:-1] = a\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "origin_pos": 4
   },
   "source": [
    "Now let's implement it in TVM. Note that we pass the four condition values into `tvm.any`.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "origin_pos": 5,
    "tab": [
     "tvm"
    ]
   },
   "outputs": [],
   "source": [
    "p = 1 # padding size\n",
    "n, m = te.var('n'), te.var('m')\n",
    "A = te.placeholder((n, m), name='a')\n",
    "B = te.compute((n+p*2, m+p*2),\n",
    "                lambda i, j: te.if_then_else(\n",
    "                    te.any(i<p, i>=n+p, j<p, j>=m+p), 0, A[i-p, j-p]),\n",
    "                name='b')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "origin_pos": 6
   },
   "source": [
    "Verify the results.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "origin_pos": 7,
    "tab": [
     "tvm"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0. 0. 0. 0. 0. 0.]\n",
      " [0. 1. 1. 1. 1. 0.]\n",
      " [0. 1. 1. 1. 1. 0.]\n",
      " [0. 1. 1. 1. 1. 0.]\n",
      " [0. 0. 0. 0. 0. 0.]]\n"
     ]
    }
   ],
   "source": [
    "s = te.create_schedule(B.op)\n",
    "mod = tvm.build(s, [A, B])\n",
    "c = tvm.nd.array(np.empty_like(b))\n",
    "mod(tvm.nd.array(a), c)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "origin_pos": 8
   },
   "source": [
    "## Summary\n",
    "\n",
    "- We can use `tvm.any` and `tvm.all` to construct complex conditional expressions.\n"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}